package basis.game.level;

import static java.lang.Math.*;

public class Gleam{
    
    public static void createLight(Level l,Light i){
        int ra=i.getRadius();
        for(int t=-ra;t<ra;t+=l.getTerrainSize()){
            for(int n=-ra;n<ra;n+=l.getTerrainSize()){
                Terrain ter=l.getTerrainAt(t+i.getX(),n+i.getY());
                if(ter==null) continue;
                double angle=atan2(ter.getCenterX()-i.getX(),ter.getCenterY()-i.getY());
                if(i.getLowerBound()<=angle&&i.getUpperBound()>=angle)
                    if(seeable(l,i.getX(),i.getY(),ter.getCenterX(),ter.getCenterY())){
                        calculateLight(ter,i);
                    }
            }
        }
    }

    public static boolean seeable(Level l,double x1,double y1,double x2,double y2){
        double angle=atan2(y2-y1,x2-x1);
        double length=sqrt(pow(x2-x1,2)+pow(y2-y1,2));
        for(double d=0;d<length;d+=l.getTerrainSize()/4.){
            Terrain t=l.getTerrainAt(x1+d*cos(angle),y1+d*sin(angle));
            if(t!=null)
                if(t.isSolid()){
                    return false;
                }
        }
        return true;
    }

    private static void calculateLight(Terrain ter,Light i) {
        double distance=sqrt(pow(ter.getCenterX()-i.getX(),2)+pow(ter.getCenterY()-i.getY(),2));
        if(distance>i.getRadius()) return;
        double level=i.getBrightness()*exp(-1./i.getRadius()*distance);
        level=(level>255)?255:((level<0)?0:level);
        int red=(int)round((i.getColor()>>16&0xff)*level/255.);
        int green=(int)round((i.getColor()>>8&0xff)*level/255.);
        int blue=(int)round((i.getColor()&0xff)*level/255.);
        int r=(red>(ter.getLight()>>16&0xff))?red:ter.getLight()>>16&0xff;
        int g=(green>(ter.getLight()>>8&0xff))?green:ter.getLight()>>8&0xff;
        int b=(blue>(ter.getLight()&0xff))?blue:ter.getLight()&0xff;
        int light=r<<16|g<<8|b;
        ter.setLight(light);
    }
    
}